//
//  MKVideoViewCell.swift
//  MKPhotoDetailDemo
//
//  Created by 劢克科技 on 2019/3/27.
//  Copyright © 2019 劢克科技. All rights reserved.
//

import UIKit
import AVFoundation

class MKVideoViewCell: UICollectionViewCell {
    
    //MARK: - Life Cycle
    
    override func prepareForReuse() {
        super.prepareForReuse()
        
        startInteract = false
        shouldStart = false
        url = nil
        thumbUrl = ""
        thumb.image = nil
        thumb.removeFromSuperview()
        loading.removeFromSuperview()
        removePeriodicTimeObserver()
        deinitVideo()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = UIColor.black
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //MARK: - Setter
    
    var imageData: MKImageData?

    var url: URL? {
        didSet {
            initVideo()
            if url != nil {
                thumbUrl = "\((url?.absoluteString)!).jpg"
            }
        }
    }
    
    var thumbUrl = "" {
        didSet {
            self.addSubview(self.loading)
            self.loading.center = CGPoint(x: self.bounds.width / 2, y: self.bounds.height / 2)
            let animate = CABasicAnimation(keyPath: "transform.rotation.z")
            animate.duration = 1.5
            animate.repeatCount = 9999
            animate.toValue = Double.pi * 2
            self.loading.layer.removeAllAnimations()
            self.loading.layer.add(animate, forKey: "")
        }
    }
    var currentIndex = 0
    var startPoint: CGPoint?
    var layerPoint = CGPoint.zero
    var startInteract = false
    var shouldStart = false
    
    fileprivate func setUpText() {
        addSubview(textView)
        textView.leftAnchor.constraint(equalTo: leftAnchor, constant: 0).isActive = true
        textView.rightAnchor.constraint(equalTo: rightAnchor, constant: 0).isActive = true
        if #available(iOS 11.0, *) {
            textView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
        } else {
            textView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 0).isActive = true
        }
        
        textView.addSubview(textTitle)
        textTitle.leftAnchor.constraint(equalTo: textView.leftAnchor, constant: 10).isActive = true
        textTitle.topAnchor.constraint(equalTo: textView.topAnchor, constant: 10).isActive = true
        
        textView.addSubview(button)
        button.rightAnchor.constraint(equalTo: textView.rightAnchor, constant: -10).isActive = true
        button.topAnchor.constraint(equalTo: textView.topAnchor, constant: 5).isActive = true
        
        textView.addSubview(textSort)
        textSort.leftAnchor.constraint(equalTo: textView.leftAnchor, constant: 10).isActive = true
        textSort.topAnchor.constraint(equalTo: textTitle.bottomAnchor, constant: 5).isActive = true
        
        textView.addSubview(textContent)
        textContent.leftAnchor.constraint(equalTo: textView.leftAnchor, constant: 10).isActive = true
        textContent.topAnchor.constraint(equalTo: textSort.bottomAnchor, constant: 5).isActive = true
        textContent.rightAnchor.constraint(equalTo: textView.rightAnchor, constant: -10).isActive = true
        
        textView.addSubview(textTime)
        textTime.leftAnchor.constraint(equalTo: textView.leftAnchor, constant: 10).isActive = true
        textTime.topAnchor.constraint(equalTo: textContent.bottomAnchor, constant: 5).isActive = true
        textTime.bottomAnchor.constraint(equalTo: textView.bottomAnchor, constant: -10).isActive = true
    }
    
    var textInfo = false {
        didSet {
            if textInfo {
                textTitle.text = imageData?.username
                textSort.text = imageData?.sortname
                textContent.text = imageData?.content
                textTime.text = imageData?.time
                setUpText()
            }
        }
    }
    
    //MARK: - Getter
    
    var delegate: MKImageViewCellDelegate?
    
    var asset: AVAsset?
    var player: AVPlayer?
    var playerItem: AVPlayerItem?
    var playerLayer: AVPlayerLayer?
    var timeObserverToken: Any?
    
    lazy var thumb: UIImageView = {
        let thumb = UIImageView()
        thumb.contentMode = .scaleAspectFill
        thumb.clipsToBounds = true
        return thumb
    }()
    
    lazy var loading: UIImageView = {
        let imageV = UIImageView()
        imageV.image = #imageLiteral(resourceName: "loading")
        imageV.contentMode = .scaleAspectFill
        imageV.clipsToBounds = true
        imageV.frame = CGRect(x: 0, y: 0, width: 36, height: 36)
        return imageV
    }()
    
    lazy var textView: UIView = {
        let view = UIView()
        view.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.7999284771)
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    lazy var textTitle: UILabel = {
        let label = UILabel()
        label.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
        label.font = UIFont.systemFont(ofSize: 16)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    lazy var textSort: UILabel = {
        let label = UILabel()
        label.textColor = #colorLiteral(red: 0.6077751517, green: 0.6078823209, blue: 0.6077683568, alpha: 1)
        label.font = UIFont.systemFont(ofSize: 14)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    lazy var textContent: UILabel = {
        let label = UILabel()
        label.numberOfLines = 2
        label.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
        label.font = UIFont.systemFont(ofSize: 14)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    lazy var textTime: UILabel = {
        let label = UILabel()
        label.textColor = #colorLiteral(red: 0.6077751517, green: 0.6078823209, blue: 0.6077683568, alpha: 1)
        label.font = UIFont.systemFont(ofSize: 14)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    lazy var button: UIButton = {
        let btn = UIButton(type: .system)
        btn.setTitle("查看详情", for: .normal)
        btn.translatesAutoresizingMaskIntoConstraints = false
        btn.addTarget(self, action: #selector(handleBtn), for: .touchUpInside)
        return btn
    }()
    
    @objc fileprivate func handleBtn() {
        delegate?.btnClick(index: currentIndex)
    }
    
    //MARK: - 初始化视频
    
    fileprivate func addPeriodicTimeObserver() {
        let timeScale = CMTimeScale(NSEC_PER_SEC)
        let time = CMTime(seconds: 0.3, preferredTimescale: timeScale)
        
        timeObserverToken = player?.addPeriodicTimeObserver(forInterval: time, queue: .main, using: { (time) in
            if self.loading.superview != nil && time.timescale == timeScale {
                self.loading.removeFromSuperview()
            }
            if self.playerItem?.duration.seconds == time.seconds {
                self.player?.seek(to: CMTime(value: 0, timescale: timeScale), completionHandler: { (_) in
                    self.player?.play()
                })
            }
        })
    }
    
    func removePeriodicTimeObserver() {
        if let timeObserverToken = timeObserverToken {
            player?.removeTimeObserver(timeObserverToken)
            self.timeObserverToken = nil
        }
    }
    
    func initVideo() {
        if url != nil {
            asset = AVAsset(url: url!)
            playerItem = AVPlayerItem(asset: asset!)
            player = AVPlayer(playerItem: playerItem)
            playerLayer = AVPlayerLayer(player: player)
            playerLayer?.frame = bounds
            layer.addSublayer(playerLayer!)
            player?.play()
            
            // 添加手势
            let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(gesture:)))
            panGesture.delegate = self
            self.addGestureRecognizer(panGesture)
            
            // 监听视频的状态
            addPeriodicTimeObserver()
        }
    }
    
    //MARK: - 销毁视频
    
    func deinitVideo() {
        removePeriodicTimeObserver()
        playerLayer?.removeFromSuperlayer()
        asset = nil
        player = nil
        playerItem = nil
        playerLayer = nil
    }
    
    //MARK: - Gesture
    
    @objc fileprivate func handlePanGesture(gesture: UIPanGestureRecognizer) {
        if playerLayer == nil {
            return
        }
        let location = gesture.location(in: self)
        var percent: CGFloat = 0
        if startPoint != nil {
            percent = abs(location.y - startPoint!.y) / UIScreen.main.bounds.height * 2
        }
        
        if gesture.state == .began {
            startPoint = gesture.location(in: self)
            layerPoint = (playerLayer?.position)!
        } else if gesture.state == .changed {
            if startInteract == false {
                let offsetY = abs(startPoint!.y - location.y)
                let offsetX = abs(startPoint!.x - location.x)
                if offsetY + offsetX >= 5 {
                    startInteract = true
                    shouldStart = offsetY > offsetX + 3
                }
                
                if shouldStart == true && frame.origin.x != UIScreen.main.bounds.width * CGFloat(currentIndex) {
                    shouldStart = false
                }
            }
            if startInteract && shouldStart {
                // 开始交互动画
                textView.alpha = 0
                delegate?.clearBg()
                delegate?.shouldScroll(bool: false)
                let offsetY = startPoint!.y - location.y
                let y = -offsetY
                layerOffsetY(y: y, duration: 0)
                alpha = (1.0 - percent) * 2
            }
        } else if gesture.state == .ended {
            
            if shouldStart && startInteract {
                if percent > 0.3 {
                    let y = location.y - startPoint!.y > 0 ? UIScreen.main.bounds.height : -UIScreen.main.bounds.height
                    self.layerOffsetY(y: y, duration: 0)
                    UIView.animate(withDuration: 0.25, animations: {
                        self.alpha = 0
                    }) { (_) in
                        self.delegate?.dismissNow()
                    }
                } else {
                    // 取消
                    delegate?.shouldScroll(bool: true)
                    self.layerOffsetY(y: 0, duration: 0)
                    UIView.animate(withDuration: 0.25, animations: {
                        self.alpha = 1.0
                    }) { (_) in
                        self.delegate?.fillBg()
                        self.textView.alpha = 1
                    }
                }
            }
            startInteract = false
            shouldStart = false
        }
    }
    
    fileprivate func layerOffsetY(y: CGFloat, duration: Double) {
        let animate = CABasicAnimation(keyPath: "transform.translation.y")
        animate.toValue = y
        animate.duration = duration
        animate.isRemovedOnCompletion = false
        animate.fillMode = .forwards
        playerLayer?.add(animate, forKey: "")
        
        if thumb.superview != nil {
            thumb.layer.add(animate, forKey: "")
        }
    }
}

//MARK: - <GestureDelegate>

extension MKVideoViewCell: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}
